using System.Security.Authentication;
using Lemon.Common.Extend;
using Microsoft.Extensions.Configuration;
using RabbitMQ.Client;

namespace Lemon.BackgroundJobs.RabbitMQ;

public class RabbitMQClient : IRabbitMQClient
{
    private readonly RabbitMQConfig _rabbitMqConfig;

    /// <summary>
    /// RabbitMQ客户端管理类
    /// </summary>
    /// <param name="configuration"></param>
    public RabbitMQClient(IConfiguration configuration)
    {
        string hostName = configuration.GetSection("RabbitMQ:HostName").Value;
        int port = configuration.GetSection("RabbitMQ:Port").Value.ToInt();
        string userName = configuration.GetSection("RabbitMQ:UserName").Value;
        string password = configuration.GetSection("RabbitMQ:Password").Value;
        _rabbitMqConfig = new RabbitMQConfig(hostName, port, userName, password);
    }

    private static ConnectionFactory? _connectionFactory;

    private ConnectionFactory ConnectionFactory
    {
        get
        {
            if (_connectionFactory == null)
            {
                _connectionFactory = new ConnectionFactory
                {
                    HostName = _rabbitMqConfig.HostName,
                    Port = _rabbitMqConfig.Port,
                    UserName = _rabbitMqConfig.UserName,
                    Password = _rabbitMqConfig.Password,
                    AmqpUriSslProtocols = SslProtocols.Tls,
                    AutomaticRecoveryEnabled = true, //自动重连
                    RequestedFrameMax = uint.MaxValue,
                    RequestedHeartbeat = TimeSpan.FromSeconds(ushort.MaxValue) //心跳超时时间
                };
            }

            return _connectionFactory;
        }
    }

    private static IConnection? _connection;

    /// <summary>
    /// mq连接
    /// </summary>
    public IConnection GetConnection()
    {
        if (_connection == null)
        {
            _connection = CreateNewConnection();
        }

        return _connection;
    }

    /// <summary>
    /// 创建新连接
    /// </summary>
    /// <returns></returns>
    public IConnection CreateNewConnection()
    {
        return ConnectionFactory.CreateConnection();
    }
}